# same as previous one, except want to make everything possible to be customizable...
# instead of command file need to have template_fsf file
# usually will give model info at command line or through a file
# ?there is the option of automatically generating the feat file for 6 nuisance covariates?
# or really the thing to set is orthogonalization numbers
# maybe have text file with normal info of ev title, ev location, and orthogonalization

# in another file will create a temporary text file and create the feat for the residuals
# want to have this happen in another directory (?no_nuisance?)
# also keep the residual info in here
# in subsequent analysis these residuals are what will be used

#!/usr/bin/env bash

# PACKAGE: Gunther
# VERSION: 2.0
# DATE: 10/25/08
# AUTHOR(S): Zarrar Shehzad

# Create fsf design file for FSL

# INCLUDE
source "$GUNTHERDIR/include/Asourceall.sh"


# FSF TEMPLATES
baseTemplate="${GUNTHERDIR}/etc/template_base.fsf"
evTemplate="${GUNTHERDIR}/etc/template_ev.fsf"
evOrtTemplate="${GUNTHERDIR}/etc/template_evOrt.fsf"
preconTemplate="${GUNTHERDIR}/etc/template_precon.fsf"
conTemplate="${GUNTHERDIR}/etc/template_con.fsf"
vecTemplate="${GUNTHERDIR}/etc/template_conVec.fsf"
endTemplate="${GUNTHERDIR}/etc/template_end.fsf"
# VARIABLES
subject="SUBZARRAR"
expTitle=""
source ${gSubConfigFile}
toIgnore=0
fsfPath=`pwd`
evFile=""
evName=""
ortFile=""
conFile=""
setFeatwatcher=0
setInput=""
setOutput=""
setVolDelete="0"
setPrewhiten=1
setModelType=2 # OPTIONS 0:OLS, 1:FLAME1+2, 2:FLAME1, 3:FE
setPoststats=1
setThreshMask=""
setThreshType=3 # Options 0:None, 1:Uncorrected, 2:Voxel, 3:Cluster
setPthresh=0.05
setZthresh=2.3

# USAGE
function usage {
    changegood green
    echo
    echo "Usage"
    echo "  $0 [OPTIONS] -B /fmri/data -T acc1 -E acc1 -j sub8005"
    echo "Program:"
    echo "   Create .fsf design file for use with fsl intended for individual subject stats/post-stats"
    echo "Required Options:"
    echo "  * -T"
    echo "  * -e or -E"
    echo "Available Options:"
    echo "  -T: experiment title, this will serve as the file name for your generated fsf file and will also serve as the name for the output feat directory if none is specified with the -o option (REQUIRED)"
    echo "  -e: file with ev info; ev names/titles must be in the first column and ev file paths must be in the second column, subsequent columns can have orthogonalization info (THIS OR -E IS REQUIRED)"
    echo "  -E: ev name; this will be used as the ev name/title and as your ev filename with ${gTS_EXT} added as the extension (THIS OR -e IS REQUIRED)"
    echo "  -N: file with contrast info; contrast name/title must be in the first column and the subsequent columns can have the values for the different contrasts"
    echo "  -j: template subject name (default: ${subject})"
    echo "  -i: input 4D file, you can modify this file directly or through its parts, i.e. /gDIR_DATA/subject/gDIR_FUNC/gFN_FUNCPP (default: ${funcPP})"
    echo "  -b: output directory path for generated fsf file (default: ${fsfPath})"
    echo "  -o: output feat directory (default: ${featsDir}/EXPERIMENT_TITLE)"
    echo "  -g: ignore checking for old feat directory"
    echo "  -w: turn on feat watcher"
    echo "  -d: number of initial volumes to delete (default: ${SET_VOLDELETE})"
    echo "  -W: turn OFF pre-whitening"
    echo "  -G: turn OFF post-stats"
    echo "  -m: set the model-type; options: 0->OLS, 1->FLAME 1+2, 2->FLAME, 3->Fixed-Effects (default: ${setModelType})"
    echo "  -M: input a pre-threshold mask"
    echo "  -H: set the type of threshold correction for multiple-comparisons; options: 0->None, 1->Uncorrected, 2->Voxelwise, 3->Cluster (default: ${setThreshType})"
    echo "  -p: set the probability threshold (default: ${setPthresh})"
    echo "  -z: set the z-score threshold (default: ${setZthresh})"
    standardUsage "$1"
    echo
    changebad
}

if [[ "$#" = 0 ]]; then
    usage
    exit 2
fi

# PARSE OPTIONS
while getopts ":j:T:b:i:o:ge:E:N:wd:WGm:M:H:p:z:${standardOptList}" Option; do    
    case $Option in
        j ) subject="$OPTARG"
            ;;
        T ) expTitle="$OPTARG"
            ;;
        b ) if [[ -d "$OPTARG" ]]; then
                fsfPath="$OPTARG"
            else
                zerror "Output directory '$OPTARG' for generated fsf file does not exist"
                exit -1
            fi
            ;;
        i ) setInput="$OPTARG" # CHECK IF EXISTS LATER
            ;;
        o ) setOutput="$OPTARG" # CHECK IF EXISTS LATER
            ;;
        g ) toIgnore=1
            ;;
        e ) if [[ -e "$OPTARG" ]]; then
                evFile="$OPTARG"
            else
                zerror "Given file with ev information '$OPTARG' does not exist"
                exit -1
            fi
            ;;
        E ) evName="$OPTARG"
            ;;
        N ) if [[ -e "$OPTARG" ]]; then
                conFile="$OPTARG"
            else
                zerror "Given file '$OPTARG' with contrast info does not exist"
                exit -1
            fi
            ;;
        w ) setFeatwatcher=1
            ;;
        d ) setVolDelete="$OPTARG"
            ;;
        W ) setPrewhiten=0
            ;;
        G ) setPoststats=0
            ;;
        m ) case "$OPTARG" in
            0 | 1 | 2 | 3 )
                setModelType="$OPTARG"
                ;;
            * )
                zerror "-m $OPTARG is invalid, must be from 0-3"
                exit -1
                ;;
            esac
            ;;
        M ) if [[ -e "$OPTARG" ]]; then
                setThreshMask="$OPTARG"
            else
                zerror "Pre-threshold mask '$OPTARG' does not exist"
                exit -1
            fi
            ;;
        H) case "$OPTARG" in
            0 | 1 | 2 | 3 )
                setThreshType="$OPTARG"
                ;;
            * )
                zerror "-H $OPTARG is invalid, must be from 0-3"
                exit -1
                ;;
            esac
            ;;
        p ) setPthresh="$OPTARG"
            ;;
        z ) setZthresh="$OPTARG"
            ;;
        * ) # Reference standard options found in options.sh
            standardOpts "$Option" "$OPTARG"
            ;;
    esac
done

## save command
command="$@"
## move past any options
shift $((${OPTIND}-1))

# Give user feedback of what is running
ztitle "Executing: '$0 ${command}'"

## TODO ADD the addline command so that extra line is for sure in these files...have this be command line function with possibility of sending as many files as possible (do this for subject and mask file lists in their respective functions)

# CHECKS
## experiment title
if [[ -z "$expTitle" ]]; then
    zerror "Must give an experiment title!"
    exit -1
fi
## set fsf file
fsfFile="${fsfPath}/${expTitle}.fsf"
checkOutput "$fsfFile"
if [[ "$?" -ne 0 ]]; then
    zinfo "exiting"
    exit -1
fi
## set input functional file
if [[ -z "$setInput" ]]; then
    source ${gSubConfigFile}
    setInput="${funcPP}"
fi
checkReqFile "$setInput"
## set output feat directory
if [[ -z "$setOutput" ]]; then
    source ${gSubConfigFile}
    setOutput="${featsDir}/${expTitle}.feat"
fi
checkOutput "$setOutput"
if [[ "$?" -ne 0 && "$toIgnore" = 0 ]]; then
   zerror "Output feat directory '${setOutput}' exists, can use -f to overwrite or -g to ignore this error"
   exit -1
fi
## set evs
if [[ ! -z "${evFile}" && ! -z "${evName}" ]]; then
    zerror "Cannot specify both an evFile (-e) and an evName (-E)"
    exit -1
elif [[ -z "${evFile}" && -z "${evName}" ]]; then
    zerror "Must specify one of two options: -e or -E"
    exit -1
elif [[ ! -z "${evName}" ]]; then
    evFile=`mktemp`
    zinfo "Creating temporary ev info file '${evFile}'"
    echo "${evName} ${tsDir}/${evName}.1D" > ${evFile}
    echo "" >> ${evFile}
fi
numEVs=`awk 'NF > 0' ${evFile} | wc -l`
## set cons
if [[ -z "${conFile}" ]]; then
    conTemp=1
    conFile=`mktemp`
    zinfo "Creating temporary contrast info file '${conFile}"
    echo -n "global " > ${conFile}
    if [[ "${numEVs}" -eq 1 ]]; then
       echo -n "1" >> ${conFile}
    else
       for (( i = 1; i < "${numEVs}"; i++ )); do
           echo -n "0 " >> ${conFile}
       done
       echo -n "1" >> ${conFile}
    fi
    echo "" >> ${conFile}
fi
numCons=`awk 'NF > 0' ${conFile} | wc -l`


# 1. Once for the beginning
ztitle "Creating feat"
zinfo "1. Starting first segment - Basics"
numVols=$( fslnvols ${setInput} )
tmpOutput=$( echo ${setOutput} | sed -e 's/\//\\\//g' )
tmpInput=$( echo ${setInput} | sed -e 's/\//\\\//g' )
sed -e "s/SET_FEATWATCHER/${setFeatwatcher}/" -e "s/SET_OUTPUTDIR/${tmpOutput}/" -e "s/SET_TR/${gTR}/" -e "s/SET_NVOLS/${numVols}/" -e "s/SET_VOLDELETE/${setVolDelete}/" -e "s/SET_PREWHITEN/${setPrewhiten}/" -e "s/SET_MODELTYPE/${setModelType}/" -e "s/SET_NUMEVS/${numEVs}/g" -e "s/SET_NUMCONS/${numCons}/g" -e "s/SET_POSTSTATS/${setPoststats}/" -e "s/SET_THRESHMASK/${setThreshMask}/" -e "s/SET_THRESHTYPE/${setThreshType}/" -e "s/SET_PROBTHRESH/${setPthresh}/" -e "s/SET_ZTHRESH/${setZthresh}/" -e "s/SET_INPUT/${tmpInput}/" ${baseTemplate} > ${fsfFile}

# 2. LOOP THROUGH EVS
evNum=0
declare -a evInfo
zinfo "2. Starting second segment - EVs"
echo "" >> ${fsfFile}
while read evLine; do
    # 2.1. Set main ev setting
    ## check line
    if [[ -z "$evLine" ]]; then
        continue
    fi
    ## variables
    evNum=$(( ${evNum} + 1 ))
    evInfo=( `echo "$evLine"` )
    ## spit out info
    zinfo " Processing EV #${evNum}: ${evInfo[0]}"
    ## check title
    if [[ "${#evInfo[@]}" -lt 2 ]]; then
        zerror "Need to have at least two variables per line (e.g., ev-title ev-filename)"
        exit -1
    fi
    ## check file
    if [[ ! -e "${evInfo[1]}" ]]; then
        zerror "EV file '${evInfo[1]}' not found"
        exit -1
    else
        zinfo "...located EV file: ${evInfo[1]}"
    fi
    ## Add to FSF file with ev settings
    tmpEvInfo=$( echo ${evInfo[1]} | sed -e 's/\//\\\//g' )
    sed -e "s/SET_EVNUMBER/${evNum}/g" -e "s/SET_EVTITLE/${evInfo[0]}/" -e "s/SET_EVFILE/${tmpEvInfo}/" ${evTemplate} >> ${fsfFile}
    ## Delete unneeded vars
    unset evInfo[0]
    unset evInfo[1]
    ## Copy vars for next step
    ortInfo=( "${evInfo[@]}" )
    
    # 2.2. Set ort values
    zinfo "...processing orthogonalization settings"
    if [[ "${#ortInfo[@]}" -gt "$numEVs" ]]; then
        zerror "Too many orthogonalization variables (${#ortInfo[@]})"
        exit -1
    fi
    ## set initial ort
     sed -e "s/SET_EVNUMBER/${evNum}/g" -e "s/SET_ORTNUMBER/0/g" -e "s/SET_ORTVALUE/1/" ${evOrtTemplate} >> ${fsfFile}
    ## set ort options
    for (( i=0; i < "${numEVs}"; i++ )); do
        ## default ort option is 0
        if [[ -z "${ortInfo[$i]}" ]]; then
            ortInfo[$i]=0
        fi
        ## set ort number
        ortNum=$(( $i + 1 ))
        ## Add to FSF file with ort setting
        sed -e "s/SET_EVNUMBER/${evNum}/g" -e "s/SET_ORTNUMBER/${ortNum}/g" -e "s/SET_ORTVALUE/${ortInfo[$i]}/" ${evOrtTemplate} >> ${fsfFile}
    done
done < "${evFile}"

# 2. LOOP THROUGH CONTRASTS
zinfo "3. Starting third segment - Contrasts"
## Add initial part of contrasts
cat ${preconTemplate} >> ${fsfFile}
## Setup (real)
conNum=0
conType="real"
declare -a conInfo
while read conLine; do
    ## check line
    if [[ -z "$conLine" ]]; then
        continue
    fi
    ## variables
    conNum=$(( ${conNum} + 1 ))
    conInfo=( `echo "$conLine"` )
    ## spit out info
    zinfo " Processing Contrast (real) #${conNum}: ${conInfo[0]}"
    ## check title
    if [[ "${#conInfo[@]}" -lt 1 ]]; then
        zerror "Need to have at least two variables per line (e.g., con-title con-onoff)"
        exit -1
    fi
    ## set stuff
    sed -e "s/SET_CONTRASTTYPE/${conType}/g" -e "s/SET_CONTRASTNUMBER/${conNum}/g" -e "s/SET_CONTRASTNAME/${conInfo[0]}/g" ${conTemplate} >> ${fsfFile}
    ## Delete unneeded vars
    unset conInfo[0]
    ## Copy vars for next step
    vecInfo=( "${conInfo[@]}" )
    
    # Check number of contrast vectors
    if [[ "${#vecInfo[@]}" -gt "${numEVs}" ]]; then
        zerror "Number of contrast vectors '${#vecInfo[@]}' given is larger than number of EVs '${numEVs}'"
        exit -1
    fi
    # Set contrast vectors
    for (( i = 0; i < "${numEVs}"; i++ )); do
        ## default contrast vector is 0
        if [[ -z "${vecInfo[$i]}" ]]; then
            vecInfo[$i]=0
        fi
        ## set value
        vecNum=$(( $i + 1 ))
        sed -e "s/SET_CONTYPE/${conType}/g" -e "s/SET_CONNUM/${conNum}/g" -e "s/SET_VECNUM/${vecNum}/g" -e "s/SET_VECVALUE/${vecInfo[$i]}/g" ${vecTemplate} >> ${fsfFile}
    done
done < "$conFile"

## Setup (orig)
conNum=0
conType="orig"
declare -a conInfo
while read conLine; do
    ## check line
    if [[ -z "$conLine" ]]; then
        continue
    fi
    ## variables
    conNum=$(( ${conNum} + 1 ))
    conInfo=( `echo "$conLine"` )
    ## spit out info
    zinfo " Processing Contrast (orig) #${conNum}: ${conInfo[0]}"
    ## check title
    if [[ "${#conInfo[@]}" -lt 1 ]]; then
        zerror "Need to have at least two variables per line (e.g., con-title con-onoff)"
        exit -1
    fi
    ## set stuff
    sed -e "s/SET_CONTRASTTYPE/${conType}/g" -e "s/SET_CONTRASTNUMBER/${conNum}/g" -e "s/SET_CONTRASTNAME/${conInfo[0]}/g" ${conTemplate} >> ${fsfFile}
    ## Delete unneeded vars
    unset conInfo[0]
    ## Copy vars for next step
    vecInfo=( "${conInfo[@]}" )
    
    # Check number of contrast vectors
    if [[ "${#vecInfo[@]}" -gt "${numEVs}" ]]; then
        zerror "Number of contrast vectors '${#vecInfo[@]}' given is larger than number of EVs '${numEVs}'"
        exit -1
    fi
    # Set contrast vectors
    for (( i = 0; i < "${numEVs}"; i++ )); do
        ## default contrast vector is 0
        if [[ -z "${vecInfo[$i]}" ]]; then
            vecInfo[$i]=0
        fi
        ## set value
        vecNum=$(( $i + 1 ))
        sed -e "s/SET_CONTYPE/${conType}/g" -e "s/SET_CONNUM/${conNum}/g" -e "s/SET_VECNUM/${vecNum}/g" -e "s/SET_VECVALUE/${vecInfo[$i]}/g" ${vecTemplate} >> ${fsfFile}
    done
done < "$conFile"

# Add ending
zinfo "4. Adding non-gui elements"
cat ${endTemplate} >> ${fsfFile}

# CLEAN UP
zinfo "5. Clean Up"
if [[ ! -z "${evName}" ]]; then
    zinfo "...cleaning up temporary EV File"
    zcmd "rm ${evFile}"
fi
if [[ "$conTemp" = 1 ]]; then
    zinfo "...cleaning up temporary contrast file"
    zcmd "rm ${conFile}"
fi
zinfo "Completed creation of ${fsfFile}"
